/*
 * Copyright (C) 2011  John Lawrence thegordo.john at gmail.com
 * Licensed under GPLv3 or later. see http://www.gnu.org/copyleft/gpl.html
 */

package org.jklawrencefam.annotation.smtp;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Properties;
import java.util.Set;

/**
 * User: John Lawrence
 * Date: 7/26/11
 * Time: 5:17 AM
 */
@SupportedAnnotationTypes({"org.jklawrencefam.annotation.smtp.SmtpCommandMarker"})
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class SmtpCommandProcessor extends AbstractProcessor {
    public static final String PROPERTY_FILENAME = "SmtpCommands.properties";
    public static final String ENHANCED_FILENAME = "SmtpEnhanced.conf";

    private static boolean ranOnce = false;

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        if (ranOnce) {
            return false;
        }
        Properties existingProperties = new Properties();
        try {
            existingProperties.load(getFileObjectForRead(PROPERTY_FILENAME).openInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        StringBuilder fileContents2 = new StringBuilder();
        for (Element element : roundEnv.getElementsAnnotatedWith(SmtpCommandMarker.class)) {
            SmtpCommandMarker annotation = element.getAnnotation(SmtpCommandMarker.class);
            if (annotation != null) {
                existingProperties.put(annotation.value(), element.toString());
                if (annotation.enhanced()) {
                    fileContents2.append(annotation.keyword()).append("\n");
                }
            }
        }

        StringWriter writer = new StringWriter();
        try {
            existingProperties.store(writer, "");
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            getFileObjectForWrite(PROPERTY_FILENAME).openWriter().append(writer.toString()).close();
            getFileObjectForWrite(ENHANCED_FILENAME).openWriter().append(fileContents2).close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        ranOnce = true;
        return true;
    }

    private FileObject getFileObjectForWrite(String filename) {
        CharSequence filePackage = new StringBuilder("");

        CharSequence fileName = new StringBuilder(filename);
        FileObject resource;
        Filer filer = processingEnv.getFiler();
        try {
            resource = filer.createResource(StandardLocation.CLASS_OUTPUT, filePackage, fileName);
        } catch (FilerException fe) {
            fe.printStackTrace();
            resource = null;
        } catch (IOException e) {
            System.err.println(e.getMessage());
            try {
                resource = filer.getResource(StandardLocation.CLASS_OUTPUT, filePackage, fileName);
            } catch (IOException e2) {
                System.err.println(e2.getMessage());
                resource = null;
            }
        }
        return resource;
    }

    private FileObject getFileObjectForRead(String filename) {
        CharSequence filePackage = new StringBuilder("");

        CharSequence fileName = new StringBuilder(filename);
        FileObject resource;
        Filer filer = processingEnv.getFiler();
        try {
            resource = filer.getResource(StandardLocation.CLASS_OUTPUT, filePackage, fileName);
        } catch (FilerException fe) {
            fe.printStackTrace();
            resource = null;
        } catch (IOException e) {
            System.err.println(e.getMessage());
            try {
                resource = filer.getResource(StandardLocation.CLASS_OUTPUT, filePackage, fileName);
            } catch (IOException e2) {
                System.err.println(e2.getMessage());
                resource = null;
            }
        }
        return resource;
    }
}
